#define __host__
#define __device__
#include <vector_types.h>

#include <algorithm/analytical_model/algorithm/cuda/inter_op/receiver/CylinderReceiver.h>
#include <algorithm/analytical_model/algorithm/cuda/receiver/CylinderReceiver.cuh>
#include <utils/Utils.h>

#include <memory>

using namespace solar::cuda::inter_op;

CylinderReceiver::CylinderReceiver(cudaStream_t stream)
{
    this->delegate_ptr_ = std::make_shared<solar::cuda::CylinderReceiver>(stream);
}

void CylinderReceiver::init(float pixel_per_meter_for_receiver) const
{
    this->delegate_ptr_->init(pixel_per_meter_for_receiver);
}

void CylinderReceiver::setResolution(float pixel_per_meter_for_receiver) const
{
    this->delegate_ptr_->setResolution(pixel_per_meter_for_receiver);
}

auto CylinderReceiver::getFocusCenter(const Float3& heliostat_position) const -> Float3
{
    auto result = this->delegate_ptr_->getFocusCenter(
        {heliostat_position.x, heliostat_position.y, heliostat_position.z});
    return structCopy<Float3>(result);
}

auto CylinderReceiver::intersect(const Float3& orig,
                                 const Float3& dir) const -> std::tuple<float, float, float, bool>
{
    auto ptr = std::dynamic_pointer_cast<solar::cuda::CylinderReceiver>(this->delegate_ptr_);
    return ptr->intersect(structCopy<float3>(orig), structCopy<float3>(dir));
}
